/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef FSL_OSIF_H
#define FSL_OSIF_H

#include <stdint.h>

/**
* @page misra_violations MISRA-C:2012 violations
*
* @section [global]
* Violates MISRA 2012 Advisory Rule 2.5, Global macro not referenced.
* The macro defines a value that will be interpreted as an infinite timeout.
*
*/

/*! @file */

/*!
 * @addtogroup osif
 * @{
 */

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*! @cond DRIVER_INTERNAL_USE_ONLY */

#ifdef USING_OS_FREERTOS
/* FreeRTOS implementation */
#include "FreeRTOS.h"
#include "semphr.h"
/*! @brief Type for a mutex. */
typedef SemaphoreHandle_t mutex_t;
/*! @brief Type for a semaphore. */
typedef SemaphoreHandle_t semaphore_t;

#else
/* Bare-metal implementation */
/*! @brief Type for a mutex. */
typedef uint8_t mutex_t;
/*! @brief Type for a semaphore. */
typedef volatile uint8_t semaphore_t;
#endif

/*! @endcond */

#define OSIF_WAIT_FOREVER 0xFFFFFFFFu

/*! @brief Defines the return status of osif's functions */
typedef enum
{
    OSIF_STATUS_SUCCESS = 0U, /*!< Success */
    OSIF_STATUS_FAIL   = 1U, /*!< Failed */
    OSIF_STATUS_TIMEOUT = 2U  /*!< Timeout occurred */
} osif_status_t;

/*******************************************************************************
 * API
 ******************************************************************************/

#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Delays execution for a number of milliseconds.
 *
 * @param[in] delay Time delay in milliseconds.
 */
void OSIF_TimeDelay(const uint32_t delay);


/*!
 * @brief Waits for a mutex and locks it.
 *
 * @param[in] pMutex reference to the mutex object
 * @param[in] timeout time-out value in milliseconds
 * @return  One of the possible status codes:
 * - OSIF_STATUS_SUCCESS: mutex lock operation success
 * - OSIF_STATUS_FAIL: mutex already owned by current thread
 * - OSIF_STATUS_TIMEOUT: mutex lock operation timed out
 *
 */
osif_status_t OSIF_MutexLock(const mutex_t* const pMutex, const uint32_t timeout);

/*!
 * @brief Unlocks a previously locked mutex.
 *
 * @param[in] pMutex reference to the mutex object
 * @return  One of the possible status codes:
 * - OSIF_STATUS_SUCCESS: mutex unlock operation success
 * - OSIF_STATUS_FAIL: mutex unlock failed
 */
osif_status_t OSIF_MutexUnlock(const mutex_t* const pMutex);


/*!
 * @brief Create an unlocked mutex.
 *
 * @param[in] pMutex reference to the mutex object
 * @return  One of the possible status codes:
 * - OSIF_STATUS_SUCCESS: mutex created
 * - OSIF_STATUS_FAIL: mutex could not be created
 */
osif_status_t OSIF_MutexCreate(mutex_t* const pMutex);

/*!
 * @brief Destroys a previously created mutex.
 *
 * @param[in] pMutex reference to the mutex object
 * @return  One of the possible status codes:
 * - OSIF_STATUS_SUCCESS: mutex destroyed
 */
osif_status_t OSIF_MutexDestroy(const mutex_t* const pMutex);


/*!
 * @brief Decrement a semaphore with timeout.
 *
 * @param[in] pSem reference to the semaphore object
 * @param[in] timeout time-out value in milliseconds
 * @return  One of the possible status codes:
 * - OSIF_STATUS_SUCCESS: semaphore wait operation success
 * - OSIF_STATUS_TIMEOUT: semaphore wait timed out
 */
osif_status_t OSIF_SemaWait(semaphore_t* const pSem, const uint32_t timeout);


/*!
 * @brief Increment a semaphore
 *
 * @param[in] pSem reference to the semaphore object
 * @return  One of the possible status codes:
 * - OSIF_STATUS_SUCCESS: semaphore post operation success
 * - OSIF_STATUS_FAIL: semaphore could not be incremented
 */
osif_status_t OSIF_SemaPost(semaphore_t* const pSem);


/*!
 * @brief Creates a semaphore with a given value.
 *
 * @param[in] pSem reference to the semaphore object
 * @param[in] initValue initial value of the semaphore
 * @return  One of the possible status codes:
 * - OSIF_STATUS_SUCCESS: semaphore created
 * - OSIF_STATUS_FAIL: semaphore could not be created
 */
osif_status_t OSIF_SemaCreate(semaphore_t* const pSem, const uint8_t initValue);


/*!
 * @brief Destroys a previously created semaphore.
 *
 * @param[in] pSem reference to the semaphore object
 * @return  One of the possible status codes:
 * - OSIF_STATUS_SUCCESS: semaphore destroyed
 */
osif_status_t OSIF_SemaDestroy(const semaphore_t* const pSem);

/*! @}*/
#if defined(__cplusplus)
}
#endif

/*! @}*/

#endif /* FSL_OSIF_H */
/*******************************************************************************
 * EOF
 ******************************************************************************/
